use fast_surface_nets::ndshape::Shape;

/// 运行时 shape，告诉 surface_nets 这个标量场是 dim x dim x dim
#[derive(Clone, Copy)]
pub struct RuntimeShape3 {
    dim: u32,
}

impl RuntimeShape3 {
    pub fn new(dim: u32) -> Self {
        Self { dim }
    }
}

impl Shape<3> for RuntimeShape3 {
    type Coord = u32;

    #[inline]
    fn size(&self) -> Self::Coord {
        // 返回总体素点数量 (dim^3) 作为 u32
        // 注意：dim 是 u32，dim*dim*dim 也保持在 u32 里，假设你的块不会大到溢出 u32
        self.dim * self.dim * self.dim
    }

    #[inline]
    fn usize(&self) -> usize {
        // 同上，只是换成 usize，方便拿来 index Vec
        (self.dim as usize) * (self.dim as usize) * (self.dim as usize)
    }

    #[inline]
    fn as_array(&self) -> [Self::Coord; 3] {
        // 返回 [dim_x, dim_y, dim_z]。我们是立方体，所以全一样
        [self.dim, self.dim, self.dim]
    }

    #[inline]
    fn linearize(&self, p: [Self::Coord; 3]) -> Self::Coord {
        // (x,y,z) -> index
        // 内存布局: x + dim * (y + dim * z)
        let x = p[0];
        let y = p[1];
        let z = p[2];
        x + self.dim * (y + self.dim * z)
    }

    #[inline]
    fn delinearize(&self, i: Self::Coord) -> [Self::Coord; 3] {
        // index -> (x,y,z)
        let dim = self.dim;
        let z = i / (dim * dim);
        let yz = i - z * dim * dim;
        let y = yz / dim;
        let x = yz - y * dim;
        [x, y, z]
    }
}
